home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Common / DXUTenum.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  30.4 KB  |  869 lines

  1. //--------------------------------------------------------------------------------------
  2. // File: DXUTEnum.cpp
  3. //
  4. // Enumerates D3D adapters, devices, modes, etc.
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //--------------------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9.  
  10.  
  11. //--------------------------------------------------------------------------------------
  12. // Forward declarations
  13. //--------------------------------------------------------------------------------------
  14. static int __cdecl SortModesCallback( const void* arg1, const void* arg2 );
  15. UINT DXUTStencilBits( D3DFORMAT fmt );
  16. UINT DXUTDepthBits( D3DFORMAT fmt );
  17. UINT DXUTAlphaChannelBits( D3DFORMAT fmt );
  18. UINT DXUTColorChannelBits( D3DFORMAT fmt );
  19. CD3DEnumeration* DXUTGetEnumeration()
  20. {
  21.     // Using an accessor function gives control of the construction order
  22.     static CD3DEnumeration d3denum;
  23.     return &d3denum;
  24. }
  25.  
  26.  
  27. //--------------------------------------------------------------------------------------
  28. CD3DEnumeration::CD3DEnumeration()
  29. {
  30.     m_pD3D = NULL;
  31.     m_IsDeviceAcceptableFunc = NULL;
  32.     m_bRequirePostPixelShaderBlending = true;
  33.  
  34.     m_nMinWidth = 0;
  35.     m_nMinHeight = 0;
  36.     m_nMaxWidth = UINT_MAX;
  37.     m_nMaxHeight = UINT_MAX;
  38.  
  39.     m_nRefreshMin = 0;
  40.     m_nRefreshMax = UINT_MAX;
  41.  
  42.     m_nMultisampleQualityMax = 0xFFFF;
  43.  
  44.     ResetPossibleDepthStencilFormats();
  45.     ResetPossibleMultisampleTypeList();                                   
  46.     ResetPossiblePresentIntervalList();
  47.     SetPossibleVertexProcessingList( true, true, true, false );
  48. }
  49.  
  50.  
  51. //--------------------------------------------------------------------------------------
  52. CD3DEnumeration::~CD3DEnumeration()
  53. {
  54.     ClearAdapterInfoList();
  55. }
  56.  
  57.  
  58.  
  59. //--------------------------------------------------------------------------------------
  60. // Enumerates available D3D adapters, devices, modes, etc.
  61. //--------------------------------------------------------------------------------------
  62. HRESULT CD3DEnumeration::Enumerate( IDirect3D9* pD3D,
  63.                                     LPDXUTCALLBACKISDEVICEACCEPTABLE IsDeviceAcceptableFunc )
  64. {
  65.     if( pD3D == NULL )
  66.     {
  67.         pD3D = DXUTGetD3DObject();
  68.         if( pD3D == NULL )
  69.             return DXUTERR_NODIRECT3D;
  70.     }
  71.  
  72.     m_pD3D = pD3D;
  73.     m_IsDeviceAcceptableFunc = IsDeviceAcceptableFunc;
  74.  
  75.     HRESULT hr;
  76.     ClearAdapterInfoList();
  77.     CGrowableArray<D3DFORMAT> adapterFormatList;
  78.  
  79.     const D3DFORMAT allowedAdapterFormatArray[] = 
  80.     {   
  81.         D3DFMT_X8R8G8B8, 
  82.         D3DFMT_X1R5G5B5, 
  83.         D3DFMT_R5G6B5, 
  84.         D3DFMT_A2R10G10B10
  85.     };
  86.     const UINT allowedAdapterFormatArrayCount  = sizeof(allowedAdapterFormatArray) / sizeof(allowedAdapterFormatArray[0]);
  87.  
  88.     UINT numAdapters = pD3D->GetAdapterCount();
  89.     for (UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++)
  90.     {
  91.         CD3DEnumAdapterInfo* pAdapterInfo = new CD3DEnumAdapterInfo;
  92.         if( pAdapterInfo == NULL )
  93.             return E_OUTOFMEMORY;
  94.  
  95.         pAdapterInfo->AdapterOrdinal = adapterOrdinal;
  96.         pD3D->GetAdapterIdentifier(adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier);
  97.  
  98.         // Get list of all display modes on this adapter.  
  99.         // Also build a temporary list of all display adapter formats.
  100.         adapterFormatList.RemoveAll();
  101.  
  102.         for( UINT iFormatList = 0; iFormatList < allowedAdapterFormatArrayCount; iFormatList++ )
  103.         {
  104.             D3DFORMAT allowedAdapterFormat = allowedAdapterFormatArray[iFormatList];
  105.             UINT numAdapterModes = pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat );
  106.             for (UINT mode = 0; mode < numAdapterModes; mode++)
  107.             {
  108.                 D3DDISPLAYMODE displayMode;
  109.                 pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode );
  110.  
  111.                 if( displayMode.Width < m_nMinWidth ||
  112.                     displayMode.Height < m_nMinHeight || 
  113.                     displayMode.Width > m_nMaxWidth ||
  114.                     displayMode.Height > m_nMaxHeight || 
  115.                     displayMode.RefreshRate < m_nRefreshMin ||
  116.                     displayMode.RefreshRate > m_nRefreshMax )
  117.                 {
  118.                     continue;
  119.                 }
  120.  
  121.                 pAdapterInfo->displayModeList.Add( displayMode );
  122.                 
  123.                 if( !adapterFormatList.Contains(displayMode.Format) )
  124.                     adapterFormatList.Add( displayMode.Format );
  125.             }
  126.  
  127.         }
  128.  
  129.         D3DDISPLAYMODE displayMode;
  130.         pD3D->GetAdapterDisplayMode( adapterOrdinal, &displayMode );
  131.         if( !adapterFormatList.Contains(displayMode.Format) )
  132.             adapterFormatList.Add( displayMode.Format );
  133.  
  134.         // Sort displaymode list
  135.         qsort( pAdapterInfo->displayModeList.GetData(), 
  136.                pAdapterInfo->displayModeList.GetSize(), sizeof( D3DDISPLAYMODE ),
  137.                SortModesCallback );
  138.  
  139.         // Get info for each device on this adapter
  140.         if( FAILED( EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) )
  141.         {
  142.             delete pAdapterInfo;
  143.             continue;
  144.         }
  145.  
  146.         // If at least one device on this adapter is available and compatible
  147.         // with the app, add the adapterInfo to the list
  148.         if( pAdapterInfo->deviceInfoList.GetSize() > 0 )
  149.         {
  150.             hr = m_AdapterInfoList.Add( pAdapterInfo );
  151.             if( FAILED(hr) )
  152.                 return hr;
  153.         } else
  154.             delete pAdapterInfo;
  155.     }
  156.  
  157.     bool bUniqueDesc = true;
  158.     CD3DEnumAdapterInfo* pAdapterInfo;
  159.     for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
  160.     {
  161.         CD3DEnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt(i);
  162.  
  163.         for( int j=i+1; j<m_AdapterInfoList.GetSize(); j++ )
  164.         {
  165.             CD3DEnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt(j);
  166.             if( _stricmp( pAdapterInfo1->AdapterIdentifier.Description, 
  167.                           pAdapterInfo2->AdapterIdentifier.Description ) == 0 )
  168.             {
  169.                 bUniqueDesc = false;
  170.                 break;
  171.             }
  172.         }
  173.  
  174.         if( !bUniqueDesc )
  175.             break;
  176.     }
  177.  
  178.     for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
  179.     {
  180.         pAdapterInfo = m_AdapterInfoList.GetAt(i);
  181.  
  182.         MultiByteToWideChar( CP_ACP, 0, 
  183.                              pAdapterInfo->AdapterIdentifier.Description, -1, 
  184.                              pAdapterInfo->szUniqueDescription, 100 );
  185.         pAdapterInfo->szUniqueDescription[100] = 0;
  186.  
  187.         if( !bUniqueDesc )
  188.         {
  189.             WCHAR sz[100];
  190.             wsprintf( sz, L" (#%d)", pAdapterInfo->AdapterOrdinal );
  191.             wcscat( pAdapterInfo->szUniqueDescription, sz );
  192.  
  193.         }
  194.     }
  195.  
  196.     return S_OK;
  197. }
  198.  
  199.  
  200.  
  201. //--------------------------------------------------------------------------------------
  202. // Enumerates D3D devices for a particular adapter.
  203. //--------------------------------------------------------------------------------------
  204. HRESULT CD3DEnumeration::EnumerateDevices( CD3DEnumAdapterInfo* pAdapterInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList )
  205. {
  206.     HRESULT hr;
  207.  
  208.     const D3DDEVTYPE devTypeArray[] = 
  209.     { 
  210.         D3DDEVTYPE_HAL, 
  211.         D3DDEVTYPE_SW, 
  212.         D3DDEVTYPE_REF 
  213.     };
  214.     const UINT devTypeArrayCount = sizeof(devTypeArray) / sizeof(devTypeArray[0]);
  215.  
  216.     // Enumerate each Direct3D device type
  217.     for( UINT iDeviceType = 0; iDeviceType < devTypeArrayCount; iDeviceType++ )
  218.     {
  219.         CD3DEnumDeviceInfo* pDeviceInfo = new CD3DEnumDeviceInfo;
  220.         if( pDeviceInfo == NULL )
  221.             return E_OUTOFMEMORY;
  222.  
  223.         // Fill struct w/ AdapterOrdinal and D3DDEVTYPE
  224.         pDeviceInfo->DeviceType = devTypeArray[iDeviceType];
  225.  
  226.         // Store device caps
  227.         if( FAILED( hr = m_pD3D->GetDeviceCaps( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, 
  228.                                               &pDeviceInfo->Caps ) ) )
  229.         {
  230.             delete pDeviceInfo;
  231.             continue;
  232.         }
  233.  
  234.         // Get info for each devicecombo on this device
  235.         if( FAILED( hr = EnumerateDeviceCombos( pAdapterInfo, pDeviceInfo, pAdapterFormatList ) ) )
  236.         {
  237.             delete pDeviceInfo;
  238.             continue;
  239.         }
  240.  
  241.         // If at least one devicecombo for this device is found, 
  242.         // add the deviceInfo to the list
  243.         if (pDeviceInfo->deviceSettingsComboList.GetSize() > 0 )
  244.             pAdapterInfo->deviceInfoList.Add( pDeviceInfo );
  245.         else
  246.             delete pDeviceInfo;
  247.     }
  248.  
  249.     return S_OK;
  250. }
  251.  
  252.  
  253.  
  254. //--------------------------------------------------------------------------------------
  255. // Enumerates DeviceCombos for a particular device.
  256. //--------------------------------------------------------------------------------------
  257. HRESULT CD3DEnumeration::EnumerateDeviceCombos( CD3DEnumAdapterInfo* pAdapterInfo, CD3DEnumDeviceInfo* pDeviceInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList )
  258. {
  259.     const D3DFORMAT backBufferFormatArray[] = 
  260.     {   
  261.         D3DFMT_A8R8G8B8, 
  262.         D3DFMT_X8R8G8B8, 
  263.         D3DFMT_A2R10G10B10, 
  264.         D3DFMT_R5G6B5, 
  265.         D3DFMT_A1R5G5B5, 
  266.         D3DFMT_X1R5G5B5 
  267.     };
  268.     const UINT backBufferFormatArrayCount = sizeof(backBufferFormatArray) / sizeof(backBufferFormatArray[0]);
  269.  
  270.     // See which adapter formats are supported by this device
  271.     for( int iFormat=0; iFormat<pAdapterFormatList->GetSize(); iFormat++ )
  272.     {
  273.         D3DFORMAT adapterFormat = pAdapterFormatList->GetAt(iFormat);
  274.  
  275.         for( UINT iBackBufferFormat = 0; iBackBufferFormat < backBufferFormatArrayCount; iBackBufferFormat++ )
  276.         {
  277.             D3DFORMAT backBufferFormat = backBufferFormatArray[iBackBufferFormat];
  278.  
  279.             for( int nWindowed = 0; nWindowed < 2; nWindowed++)
  280.             {
  281.                 if( !nWindowed && pAdapterInfo->displayModeList.GetSize() == 0 )
  282.                     continue;
  283.  
  284.                 if (FAILED( m_pD3D->CheckDeviceType( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, 
  285.                                                      adapterFormat, backBufferFormat, nWindowed )))
  286.                 {
  287.                     continue;
  288.                 }
  289.  
  290.                 if( m_bRequirePostPixelShaderBlending )
  291.                 {
  292.                     // If the backbuffer format doesn't support D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
  293.                     // then alpha test, pixel fog, render-target blending, color write enable, and dithering. 
  294.                     // are not supported.
  295.                     if( FAILED( m_pD3D->CheckDeviceFormat( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType,
  296.                                                         adapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
  297.                                                         D3DRTYPE_TEXTURE, backBufferFormat ) ) )
  298.                     {
  299.                         continue;
  300.                     }
  301.                 }
  302.  
  303.                 // If an application callback function has been provided, make sure this device
  304.                 // is acceptable to the app.
  305.                 if( m_IsDeviceAcceptableFunc != NULL )
  306.                 {
  307.                     if( !m_IsDeviceAcceptableFunc( &pDeviceInfo->Caps, adapterFormat, backBufferFormat, FALSE != nWindowed ) )
  308.                         continue;
  309.                 }
  310.                 
  311.                 // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed
  312.                 // DeviceCombo that is supported by the system and acceptable to the app. We still 
  313.                 // need to find one or more suitable depth/stencil buffer format,
  314.                 // multisample type, and present interval.
  315.                 CD3DEnumDeviceSettingsCombo* pDeviceCombo = new CD3DEnumDeviceSettingsCombo;
  316.                 if( pDeviceCombo == NULL )
  317.                     return E_OUTOFMEMORY;
  318.  
  319.                 pDeviceCombo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;
  320.                 pDeviceCombo->DeviceType = pDeviceInfo->DeviceType;
  321.                 pDeviceCombo->AdapterFormat = adapterFormat;
  322.                 pDeviceCombo->BackBufferFormat = backBufferFormat;
  323.                 pDeviceCombo->Windowed = (nWindowed != 0);
  324.                
  325.                 BuildDepthStencilFormatList( pDeviceCombo );
  326.                 BuildMultiSampleTypeList( pDeviceCombo );
  327.                 if (pDeviceCombo->multiSampleTypeList.GetSize() == 0)
  328.                 {
  329.                     delete pDeviceCombo;
  330.                     continue;
  331.                 }
  332.                 BuildDSMSConflictList( pDeviceCombo );
  333.                 BuildPresentIntervalList(pDeviceInfo, pDeviceCombo );
  334.                 pDeviceCombo->pAdapterInfo = pAdapterInfo;
  335.                 pDeviceCombo->pDeviceInfo = pDeviceInfo;
  336.  
  337.                 pDeviceInfo->deviceSettingsComboList.Add( pDeviceCombo );
  338.             
  339.             }
  340.         }
  341.     }
  342.  
  343.     return S_OK;
  344. }
  345.  
  346.  
  347.  
  348. //--------------------------------------------------------------------------------------
  349. // Adds all depth/stencil formats that are compatible with the device 
  350. //       and app to the given D3DDeviceCombo.
  351. //--------------------------------------------------------------------------------------
  352. void CD3DEnumeration::BuildDepthStencilFormatList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  353. {
  354.     D3DFORMAT depthStencilFmt;
  355.     for( int idsf = 0; idsf < m_DepthStecilPossibleList.GetSize(); idsf++ )
  356.     {
  357.         depthStencilFmt = m_DepthStecilPossibleList.GetAt(idsf);
  358.         if (SUCCEEDED(m_pD3D->CheckDeviceFormat(pDeviceCombo->AdapterOrdinal, 
  359.                 pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat, 
  360.                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFmt)))
  361.         {
  362.             if (SUCCEEDED(m_pD3D->CheckDepthStencilMatch(pDeviceCombo->AdapterOrdinal, 
  363.                     pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat, 
  364.                     pDeviceCombo->BackBufferFormat, depthStencilFmt)))
  365.             {
  366.                 pDeviceCombo->depthStencilFormatList.Add( depthStencilFmt );
  367.             }
  368.         }
  369.     }
  370. }
  371.  
  372.  
  373.  
  374.  
  375. //--------------------------------------------------------------------------------------
  376. // Adds all multisample types that are compatible with the device and app to
  377. //       the given D3DDeviceCombo.
  378. //--------------------------------------------------------------------------------------
  379. void CD3DEnumeration::BuildMultiSampleTypeList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  380. {
  381.     D3DMULTISAMPLE_TYPE msType;
  382.     DWORD msQuality;
  383.     for( int imst = 0; imst < m_MultiSampleTypeList.GetSize(); imst++ )
  384.     {
  385.         msType = m_MultiSampleTypeList.GetAt(imst);
  386.         if( SUCCEEDED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, 
  387.                 pDeviceCombo->DeviceType, pDeviceCombo->BackBufferFormat, 
  388.                 pDeviceCombo->Windowed, msType, &msQuality ) ) )
  389.         {
  390.             pDeviceCombo->multiSampleTypeList.Add( msType );
  391.             if( msQuality > m_nMultisampleQualityMax+1 )
  392.                 msQuality = m_nMultisampleQualityMax+1;
  393.             pDeviceCombo->multiSampleQualityList.Add( msQuality );
  394.         }
  395.     }
  396. }
  397.  
  398.  
  399.  
  400.  
  401. //--------------------------------------------------------------------------------------
  402. // Find any conflicts between the available depth/stencil formats and
  403. //       multisample types.
  404. //--------------------------------------------------------------------------------------
  405. void CD3DEnumeration::BuildDSMSConflictList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  406. {
  407.     CD3DEnumDSMSConflict DSMSConflict;
  408.  
  409.     for( int iDS=0; iDS<pDeviceCombo->depthStencilFormatList.GetSize(); iDS++ )
  410.     {
  411.         D3DFORMAT dsFmt = pDeviceCombo->depthStencilFormatList.GetAt(iDS);
  412.  
  413.         for( int iMS=0; iMS<pDeviceCombo->multiSampleTypeList.GetSize(); iMS++ )
  414.         {
  415.             D3DMULTISAMPLE_TYPE msType = pDeviceCombo->multiSampleTypeList.GetAt(iMS);
  416.  
  417.             if( FAILED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, pDeviceCombo->DeviceType,
  418.                                                             dsFmt, pDeviceCombo->Windowed, msType, NULL ) ) )
  419.             {
  420.                 DSMSConflict.DSFormat = dsFmt;
  421.                 DSMSConflict.MSType = msType;
  422.                 pDeviceCombo->DSMSConflictList.Add( DSMSConflict );
  423.             }
  424.         }
  425.     }
  426. }
  427.  
  428.  
  429.  
  430. //--------------------------------------------------------------------------------------
  431. // Adds all present intervals that are compatible with the device and app 
  432. //       to the given D3DDeviceCombo.
  433. //--------------------------------------------------------------------------------------
  434. void CD3DEnumeration::BuildPresentIntervalList( CD3DEnumDeviceInfo* pDeviceInfo, 
  435.                                                 CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  436. {
  437.     UINT pi;
  438.     for( int ipi = 0; ipi < m_PresentIntervalList.GetSize(); ipi++ )
  439.     {
  440.         pi = m_PresentIntervalList.GetAt(ipi);
  441.         if( pDeviceCombo->Windowed )
  442.         {
  443.             if( pi == D3DPRESENT_INTERVAL_TWO ||
  444.                 pi == D3DPRESENT_INTERVAL_THREE ||
  445.                 pi == D3DPRESENT_INTERVAL_FOUR )
  446.             {
  447.                 // These intervals are not supported in windowed mode.
  448.                 continue;
  449.             }
  450.         }
  451.         // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you
  452.         // can't do a caps check for it -- it is always available.
  453.         if( pi == D3DPRESENT_INTERVAL_DEFAULT ||
  454.             (pDeviceInfo->Caps.PresentationIntervals & pi) )
  455.         {
  456.             pDeviceCombo->presentIntervalList.Add( pi );
  457.         }
  458.     }
  459. }
  460.  
  461.  
  462.  
  463. //--------------------------------------------------------------------------------------
  464. // Release all the allocated CD3DEnumAdapterInfo objects and empty the list
  465. //--------------------------------------------------------------------------------------
  466. void CD3DEnumeration::ClearAdapterInfoList()
  467. {
  468.     CD3DEnumAdapterInfo* pAdapterInfo;
  469.     for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
  470.     {
  471.         pAdapterInfo = m_AdapterInfoList.GetAt(i);
  472.         delete pAdapterInfo;
  473.     }
  474.  
  475.     m_AdapterInfoList.RemoveAll();
  476. }
  477.  
  478.  
  479.  
  480. //--------------------------------------------------------------------------------------
  481. // Call GetAdapterInfoList() after Enumerate() to get a STL vector of 
  482. //       CD3DEnumAdapterInfo* 
  483. //--------------------------------------------------------------------------------------
  484. CGrowableArray<CD3DEnumAdapterInfo*>* CD3DEnumeration::GetAdapterInfoList()
  485. {
  486.     return &m_AdapterInfoList;
  487. }
  488.  
  489.  
  490.  
  491. //--------------------------------------------------------------------------------------
  492. CD3DEnumAdapterInfo* CD3DEnumeration::GetAdapterInfo( UINT AdapterOrdinal )
  493. {
  494.     for( int iAdapter=0; iAdapter<m_AdapterInfoList.GetSize(); iAdapter++ )
  495.     {
  496.         CD3DEnumAdapterInfo* pAdapterInfo = m_AdapterInfoList.GetAt(iAdapter);
  497.         if( pAdapterInfo->AdapterOrdinal == AdapterOrdinal )
  498.             return pAdapterInfo;
  499.     }
  500.  
  501.     return NULL;
  502. }
  503.  
  504.  
  505. //--------------------------------------------------------------------------------------
  506. CD3DEnumDeviceInfo* CD3DEnumeration::GetDeviceInfo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType )
  507. {
  508.     CD3DEnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );
  509.     if( pAdapterInfo )
  510.     {
  511.         for( int iDeviceInfo=0; iDeviceInfo<pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ )
  512.         {
  513.             CD3DEnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt(iDeviceInfo);
  514.             if( pDeviceInfo->DeviceType == DeviceType )
  515.                 return pDeviceInfo;
  516.         }
  517.     }
  518.  
  519.     return NULL;
  520. }
  521.  
  522.  
  523. //--------------------------------------------------------------------------------------
  524. // 
  525. //--------------------------------------------------------------------------------------
  526. CD3DEnumDeviceSettingsCombo* CD3DEnumeration::GetDeviceSettingsCombo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed )
  527. {
  528.     CD3DEnumDeviceInfo* pDeviceInfo = GetDeviceInfo( AdapterOrdinal, DeviceType );
  529.     if( pDeviceInfo )
  530.     {
  531.         for( int iDeviceCombo=0; iDeviceCombo<pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )
  532.         {
  533.             CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt(iDeviceCombo);
  534.             if( pDeviceSettingsCombo->AdapterFormat == AdapterFormat &&
  535.                 pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat &&
  536.                 pDeviceSettingsCombo->Windowed == bWindowed )
  537.                 return pDeviceSettingsCombo;
  538.         }
  539.     }
  540.  
  541.     return NULL;
  542. }
  543.  
  544.  
  545. //--------------------------------------------------------------------------------------
  546. // Returns the number of color channel bits in the specified D3DFORMAT
  547. //--------------------------------------------------------------------------------------
  548. UINT DXUTColorChannelBits( D3DFORMAT fmt )
  549. {
  550.     switch( fmt )
  551.     {
  552.         case D3DFMT_R8G8B8:
  553.             return 8;
  554.         case D3DFMT_A8R8G8B8:
  555.             return 8;
  556.         case D3DFMT_X8R8G8B8:
  557.             return 8;
  558.         case D3DFMT_R5G6B5:
  559.             return 5;
  560.         case D3DFMT_X1R5G5B5:
  561.             return 5;
  562.         case D3DFMT_A1R5G5B5:
  563.             return 5;
  564.         case D3DFMT_A4R4G4B4:
  565.             return 4;
  566.         case D3DFMT_R3G3B2:
  567.             return 2;
  568.         case D3DFMT_A8R3G3B2:
  569.             return 2;
  570.         case D3DFMT_X4R4G4B4:
  571.             return 4;
  572.         case D3DFMT_A2B10G10R10:
  573.             return 10;
  574.         case D3DFMT_A8B8G8R8:
  575.             return 8;
  576.         case D3DFMT_A2R10G10B10:
  577.             return 10;
  578.         case D3DFMT_A16B16G16R16:
  579.             return 16;
  580.         default:
  581.             return 0;
  582.     }
  583. }
  584.  
  585.  
  586.  
  587.  
  588. //--------------------------------------------------------------------------------------
  589. // Returns the number of alpha channel bits in the specified D3DFORMAT
  590. //--------------------------------------------------------------------------------------
  591. UINT DXUTAlphaChannelBits( D3DFORMAT fmt )
  592. {
  593.     switch( fmt )
  594.     {
  595.         case D3DFMT_R8G8B8:
  596.             return 0;
  597.         case D3DFMT_A8R8G8B8:
  598.             return 8;
  599.         case D3DFMT_X8R8G8B8:
  600.             return 0;
  601.         case D3DFMT_R5G6B5:
  602.             return 0;
  603.         case D3DFMT_X1R5G5B5:
  604.             return 0;
  605.         case D3DFMT_A1R5G5B5:
  606.             return 1;
  607.         case D3DFMT_A4R4G4B4:
  608.             return 4;
  609.         case D3DFMT_R3G3B2:
  610.             return 0;
  611.         case D3DFMT_A8R3G3B2:
  612.             return 8;
  613.         case D3DFMT_X4R4G4B4:
  614.             return 0;
  615.         case D3DFMT_A2B10G10R10:
  616.             return 2;
  617.         case D3DFMT_A8B8G8R8:
  618.             return 8;
  619.         case D3DFMT_A2R10G10B10:
  620.             return 2;
  621.         case D3DFMT_A16B16G16R16:
  622.             return 16;
  623.         default:
  624.             return 0;
  625.     }
  626. }
  627.  
  628.  
  629.  
  630.  
  631. //--------------------------------------------------------------------------------------
  632. // Returns the number of depth bits in the specified D3DFORMAT
  633. //--------------------------------------------------------------------------------------
  634. UINT DXUTDepthBits( D3DFORMAT fmt )
  635. {
  636.     switch( fmt )
  637.     {
  638.         case D3DFMT_D32F_LOCKABLE:
  639.         case D3DFMT_D32:
  640.             return 32;
  641.  
  642.         case D3DFMT_D24X8:
  643.         case D3DFMT_D24S8:
  644.         case D3DFMT_D24X4S4:
  645.         case D3DFMT_D24FS8:
  646.             return 24;
  647.  
  648.         case D3DFMT_D16_LOCKABLE:
  649.         case D3DFMT_D16:
  650.             return 16;
  651.  
  652.         case D3DFMT_D15S1:
  653.             return 15;
  654.  
  655.         default:
  656.             return 0;
  657.     }
  658. }
  659.  
  660.  
  661.  
  662.  
  663. //--------------------------------------------------------------------------------------
  664. // Returns the number of stencil bits in the specified D3DFORMAT
  665. //--------------------------------------------------------------------------------------
  666. UINT DXUTStencilBits( D3DFORMAT fmt )
  667. {
  668.     switch( fmt )
  669.     {
  670.         case D3DFMT_D16_LOCKABLE:
  671.         case D3DFMT_D16:
  672.         case D3DFMT_D32F_LOCKABLE:
  673.         case D3DFMT_D32:
  674.         case D3DFMT_D24X8:
  675.             return 0;
  676.  
  677.         case D3DFMT_D15S1:
  678.             return 1;
  679.  
  680.         case D3DFMT_D24X4S4:
  681.             return 4;
  682.  
  683.         case D3DFMT_D24S8:
  684.         case D3DFMT_D24FS8:
  685.             return 8;
  686.  
  687.         default:
  688.             return 0;
  689.     }
  690. }
  691.  
  692.  
  693.  
  694. //--------------------------------------------------------------------------------------
  695. // Used to sort D3DDISPLAYMODEs
  696. //--------------------------------------------------------------------------------------
  697. static int __cdecl SortModesCallback( const void* arg1, const void* arg2 )
  698. {
  699.     D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
  700.     D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
  701.  
  702.     if (pdm1->Width > pdm2->Width)
  703.         return 1;
  704.     if (pdm1->Width < pdm2->Width)
  705.         return -1;
  706.     if (pdm1->Height > pdm2->Height)
  707.         return 1;
  708.     if (pdm1->Height < pdm2->Height)
  709.         return -1;
  710.     if (pdm1->Format > pdm2->Format)
  711.         return 1;
  712.     if (pdm1->Format < pdm2->Format)
  713.         return -1;
  714.     if (pdm1->RefreshRate > pdm2->RefreshRate)
  715.         return 1;
  716.     if (pdm1->RefreshRate < pdm2->RefreshRate)
  717.         return -1;
  718.     return 0;
  719. }
  720.  
  721.  
  722.  
  723. //--------------------------------------------------------------------------------------
  724. CD3DEnumAdapterInfo::~CD3DEnumAdapterInfo( void )
  725. {
  726.     CD3DEnumDeviceInfo* pDeviceInfo;
  727.     for( int i=0; i<deviceInfoList.GetSize(); i++ )
  728.     {
  729.         pDeviceInfo = deviceInfoList.GetAt(i);
  730.         delete pDeviceInfo;
  731.     }
  732.     deviceInfoList.RemoveAll();
  733. }
  734.  
  735.  
  736.  
  737.  
  738. //--------------------------------------------------------------------------------------
  739. CD3DEnumDeviceInfo::~CD3DEnumDeviceInfo( void )
  740. {
  741.     CD3DEnumDeviceSettingsCombo* pDeviceCombo;
  742.     for( int i=0; i<deviceSettingsComboList.GetSize(); i++ )
  743.     {
  744.         pDeviceCombo = deviceSettingsComboList.GetAt(i);
  745.         delete pDeviceCombo;
  746.     }
  747.     deviceSettingsComboList.RemoveAll();
  748. }
  749.  
  750.  
  751. //--------------------------------------------------------------------------------------
  752. void CD3DEnumeration::ResetPossibleDepthStencilFormats()
  753. {
  754.     m_DepthStecilPossibleList.RemoveAll();
  755.     m_DepthStecilPossibleList.Add( D3DFMT_D16 );
  756.     m_DepthStecilPossibleList.Add( D3DFMT_D15S1 );
  757.     m_DepthStecilPossibleList.Add( D3DFMT_D24X8 );
  758.     m_DepthStecilPossibleList.Add( D3DFMT_D24S8 );
  759.     m_DepthStecilPossibleList.Add( D3DFMT_D24X4S4 );
  760.     m_DepthStecilPossibleList.Add( D3DFMT_D32 );
  761. }
  762.  
  763.  
  764. //--------------------------------------------------------------------------------------
  765. CGrowableArray<D3DFORMAT>* CD3DEnumeration::GetPossibleDepthStencilFormatList() 
  766. {
  767.     return &m_DepthStecilPossibleList;
  768. }
  769.  
  770.  
  771. //--------------------------------------------------------------------------------------
  772. CGrowableArray<D3DMULTISAMPLE_TYPE>* CD3DEnumeration::GetPossibleMultisampleTypeList()
  773. {
  774.     return &m_MultiSampleTypeList;
  775. }
  776.  
  777.  
  778. //--------------------------------------------------------------------------------------
  779. void CD3DEnumeration::ResetPossibleMultisampleTypeList()
  780. {
  781.     m_MultiSampleTypeList.RemoveAll();
  782.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONE );
  783.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONMASKABLE );
  784.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_2_SAMPLES );
  785.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_3_SAMPLES );
  786.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_4_SAMPLES );
  787.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_5_SAMPLES );
  788.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_6_SAMPLES );
  789.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_7_SAMPLES );
  790.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_8_SAMPLES );
  791.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_9_SAMPLES );
  792.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_10_SAMPLES );
  793.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_11_SAMPLES );
  794.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_12_SAMPLES );
  795.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_13_SAMPLES );
  796.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_14_SAMPLES );
  797.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_15_SAMPLES );
  798.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_16_SAMPLES );
  799. }
  800.  
  801.  
  802. //--------------------------------------------------------------------------------------
  803. void CD3DEnumeration::GetPossibleVertexProcessingList( bool* pbSoftwareVP, bool* pbHardwareVP, bool* pbPureHarewareVP, bool* pbMixedVP )
  804. {
  805.     *pbSoftwareVP = m_bSoftwareVP;
  806.     *pbHardwareVP = m_bHardwareVP;
  807.     *pbPureHarewareVP = m_bPureHarewareVP;
  808.     *pbMixedVP = m_bMixedVP;
  809. }
  810.  
  811.  
  812. //--------------------------------------------------------------------------------------
  813. void CD3DEnumeration::SetPossibleVertexProcessingList( bool bSoftwareVP, bool bHardwareVP, bool bPureHarewareVP, bool bMixedVP )
  814. {
  815.     m_bSoftwareVP = bSoftwareVP;
  816.     m_bHardwareVP = bHardwareVP;
  817.     m_bPureHarewareVP = bPureHarewareVP;
  818.     m_bMixedVP = bMixedVP;
  819. }
  820.  
  821.  
  822. //--------------------------------------------------------------------------------------
  823. CGrowableArray<UINT>* CD3DEnumeration::GetPossiblePresentIntervalList()
  824. {
  825.     return &m_PresentIntervalList;
  826. }
  827.  
  828.  
  829. //--------------------------------------------------------------------------------------
  830. void CD3DEnumeration::ResetPossiblePresentIntervalList()
  831. {
  832.     m_PresentIntervalList.RemoveAll();
  833.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_IMMEDIATE );
  834.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_DEFAULT );
  835.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_ONE );
  836.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_TWO );
  837.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_THREE );
  838.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_FOUR );
  839. }
  840.  
  841.  
  842. //--------------------------------------------------------------------------------------
  843. void CD3DEnumeration::SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight, 
  844.                                            UINT nMaxWidth, UINT nMaxHeight )
  845. {
  846.     m_nMinWidth = nMinWidth;
  847.     m_nMinHeight = nMinHeight;
  848.     m_nMaxWidth = nMaxWidth;
  849.     m_nMaxHeight = nMaxHeight;
  850. }
  851.  
  852.  
  853. //--------------------------------------------------------------------------------------
  854. void CD3DEnumeration::SetRefreshMinMax( UINT nMin, UINT nMax )
  855. {
  856.     m_nRefreshMin = nMin;
  857.     m_nRefreshMax = nMax;
  858. }
  859.  
  860.  
  861. //--------------------------------------------------------------------------------------
  862. void CD3DEnumeration::SetMultisampleQualityMax( UINT nMax )
  863. {
  864.     if( nMax > 0xFFFF )
  865.         nMax = 0xFFFF;
  866.     m_nMultisampleQualityMax = nMax;
  867. }
  868.  
  869.